#include "gtest/gtest.h"
#include "entitymanager.h"
#include "Entities/dummy.h"
#include "Game/Game.h"
#include <memory>
#include <Entities/plant.h>
#include <Skills/typeDefense.h>
#include <Skills/debugskill.h>

using namespace std;

//Recover skill is rewritten, test Removed;

TEST(plant_defense_test, ShieldingBuff){
    unique_ptr<Game> g(new Game());
    Actor* p1 = g->entityManager.get<entity::TestPlant>();
    Actor* p2 = g->entityManager.get<entity::TestPlant>();
    p2->learnSkill(new skill::ShieldingBuff(20));
    p2->setPos(Point(0, 1));
    g->setupBattleGround();

    int attack = stoi(p1->properties["attack"]);
    p2->properties["attack"] = p1->properties["attack"];
    EXPECT_EQ(p1->getDamage(p2, 1.0), int(attack * defenseBaseValue / (defenseBaseValue + 20)) );
    EXPECT_EQ(p2->getDamage(p1, 1.0), int(attack));
    g->dumpReplay("ShieldingBuff");
}

TEST(plant_defense_test, DecAttackBuff){
    unique_ptr<Game> g(new Game());
    Actor* p1 = g->entityManager.get<entity::TestPlant>();
    Actor* p2 = g->entityManager.get<entity::TestPlant>();
    p1->learnSkill(new skill::DecAttackBuff);
    p2->setPos(Point(0, 1));
    g->setupBattleGround();

    int attack = stoi(p1->properties["attack"]);
    p2->properties["attack"] = p1->properties["attack"];
    EXPECT_EQ(p1->getDamage(p2, 1.0), int(attack * AttackRate) );
    EXPECT_EQ(p2->getDamage(p1, 1.0), int(attack));
    g->dumpReplay("DecAttackBuff");
}

TEST(plant_defense_test, shielding_test){
    unique_ptr<Game> g(new Game());
    Actor* p1 = g->entityManager.get<entity::TestPlant>();
    p1->properties["team"] = to_string(1);
    p1->properties["energy"] = to_string(1000000);
    p1->learnSkill(new skill::Shielding);

    //Test Defense Aura
    Actor* p2 = g->entityManager.get<entity::TestPlant>();
    p2->properties["team"] = to_string(1);
    p2->learnSkill(new skill::AutoCleanse);


    Actor* p3 = g->entityManager.get<entity::TestPlant>();
    p3->properties["team"] = to_string(2);
    p3->learnSkill(new skill::AutoCleanse);

    p1->setPos(Point(0, 0));
    p2->setPos(Point(int(floor(sqrt(ShieldingRadius))), 0));
    g->setupBattleGround();

    p1->useLater("Shielding",{});
    g->oneRoundRun();
    EXPECT_TRUE(p2->hasSkill("ShieldingBuff"));
    EXPECT_FALSE(p2->hasSkill("DecAttackBuff"));
    p2->setPos(Point(int(floor(sqrt(ShieldingRadius))) + 1, 0));
    g->oneRoundRun();
    EXPECT_FALSE(p2->hasSkill("ShieldingBuff"));


    //Test Weaken Aura
    p1->setPos(Point(0, 0));
    p3->setPos(Point(int(floor(sqrt(ShieldingRadius))), 0));
    p1->useLater("Shielding",{});
    g->oneRoundRun();
    EXPECT_TRUE(p3->hasSkill("DecAttackBuff"));
    EXPECT_FALSE(p3->hasSkill("ShieldingBuff"));
    p3->setPos(Point(int(floor(sqrt(ShieldingRadius))) + 1, 0));
    g->oneRoundRun();
    EXPECT_FALSE(p3->hasSkill("DecAttackBuff"));
}